package org.xtext.runtime.term;

import java.util.Map;

import org.xtext.runtime.formula.IFormula;
import org.xtext.runtime.interpreter.Agent;
import org.xtext.runtime.type.IType;
import org.xtext.runtime.type.Type;
import org.xtext.runtime.util.Bindings;
import org.xtext.runtime.util.ILogicVisitor;

public class ListConstructor implements ITerm {
	private IFormula context;
	private ITerm guard;
	
	public ListConstructor(IFormula context, ITerm guard) {
		this.context = context;
		this.guard = guard;
	}
	
	@Override
	public IType type() {
		return Type.listType;
	}

	@Override
	public ListConstructor copy() {
		return new ListConstructor(context.copy(), guard.copy());
	}

	@Override
	public ListConstructor copy(Map<String, Variable> vars) {
		return new ListConstructor(context.copy(vars), guard.copy(vars));
	}

	@Override
	public Object value() {
		throw new UnsupportedOperationException();
	}

	public String toString() {
		return "list(" + context + "|" + guard + ")";
	}

	public boolean hasFreeVariables() {
		return context.hasFreeVariables() || guard.hasFreeVariables();
	}

	public ITerm construct(Agent agent) {
		java.util.List<Bindings> bindings = agent.queryAll(context);

//		System.out.println("bindings: " + bindings);
		if (bindings == null) return new List(new ITerm[0]);
		ITerm[] terms = new ITerm[bindings.size()];
		int i=0;
		for (Bindings binding : bindings) {
//			System.out.println(guard.copy());
			terms[i++] = guard.copy().apply(binding);
		}
		return new List(terms);
	}

	@Override
	public ITerm apply(Bindings bindings) {
		context.apply(bindings);
		return this;
	}

	@Override
	public Object accept(ILogicVisitor visitor) {
		return visitor.visit(this);
	}
}
